package earogya.ehr.patient_details;

import java.util.Iterator;
import java.util.List;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.SQLQuery;
import org.hibernate.Session;

import earogya.util.PatientDetailsHibernateUtil;;

public class HibernateManager {
	/**
	 * Save an object to database using hibernate
	 * @param obj
	 * @return
	 */
	
	
	public HibernateManager(){
	}
	
	public int saveObject(Object obj) throws HibernateException{
		Integer id=0;
		try{
		Session session = PatientDetailsHibernateUtil.getSessionFactory().getCurrentSession();
			
		session.beginTransaction();
			id=(Integer)session.save(obj);
			session.getTransaction().commit();
		}catch(HibernateException e){
				throw e;
			}
		return id;
	}
	
	/**
	 * Query results from database based on the fields and values
	 * @param fieldsAndValues - names of the columns and their respective values
	 * @param required_field - name of the required column
	 * @param table - name of the table
	 * @return
	 */
	public int queryValuesFromDatabase(Object[][] fieldsAndValues, String required_field, String table){
		int value=-1;
		Session session = PatientDetailsHibernateUtil.getSessionFactory().getCurrentSession();

		session.beginTransaction();
			SQLQuery query=session.createSQLQuery(this.buildSelectQuery(fieldsAndValues, required_field, table));
	        query.setMaxResults(1);
	        List list=query.list();
	        if(list.size()==1){
	        	value=(Integer)list.get(0);
	        }
		return value;
	}
	
	
	public List queryValueListFromDatabase(Object[][] fieldsAndValues, String required_field, String table){
		Session session = PatientDetailsHibernateUtil.getSessionFactory().getCurrentSession();
		List list=null;
		session.beginTransaction();
			SQLQuery query=session.createSQLQuery(this.buildSelectQuery(fieldsAndValues, required_field, table));
	        list=query.list();
		
		return list;
	}
	
	public List queryValueListFromDatabase(Object[][] fieldsAndValues, String[] required_field, String className, String objectName){
		Session session = PatientDetailsHibernateUtil.getSessionFactory().getCurrentSession();
		List list=null;
		//try{
			session.beginTransaction();
			Query query=session.createQuery(this.buildSelectQuery(fieldsAndValues, required_field, className, objectName));
	        list=query.list();
/*		}catch(HibernateException e){
			
		}catch(Exception e){
			System.out.println(e.getStackTrace());
		}finally{
			session.close();
		}*/
		return list;
	}
	
	/**
	 * Creates an sql query using the given information.
	 * @param fieldsAndValues - name of the columns and their respective values
	 * @param required_field - name of the required column 
	 * @param table - name of the table
	 * @return
	 */
	private String buildSelectQuery(Object[][] fieldsAndValues, String[] required_field, String className, String objectName){
		StringBuilder builder=new StringBuilder();
		builder.append("SELECT ");
		for(int i=0; i<required_field.length; i++){
			if(i<required_field.length-1){
				builder.append(objectName+"."+required_field[i]+", ");
			}
			else{
				builder.append(objectName+"."+required_field[i]+" FROM "+className+" AS "+objectName+" WHERE ");
			}
		}
		int j=0;
		for(int i=0; i<fieldsAndValues.length; i++){
			
			if(fieldsAndValues[i][1]!=null){
			if(j==0){
				builder.append(objectName+"."+fieldsAndValues[i][0]+"='"+fieldsAndValues[i][1]+"'");
			}else{
				builder.append(" AND "+objectName+"."+fieldsAndValues[i][0]+"='"+fieldsAndValues[i][1]+"'");
			}
			j++;
			}
		}
		return builder.toString();
	}
	

	/**
	 * Creates an sql query using the given information.
	 * @param fieldsAndValues - name of the columns and their respective values
	 * @param required_field - names of the required column 
	 * @param table - name of the table
	 * @return
	 */
	private String buildSelectQuery(Object[][] fieldsAndValues, String required_field, String table){
		StringBuilder builder=new StringBuilder();
		builder.append("SELECT "+required_field+" FROM "+table+" WHERE ");
		for(int i=0; i<fieldsAndValues.length; i++){
			if(i<fieldsAndValues.length-1){
				builder.append(fieldsAndValues[i][0]+"='"+fieldsAndValues[i][1]+"' AND ");
			}else{
				builder.append(fieldsAndValues[i][0]+"='"+fieldsAndValues[i][1]+"'");
			}
		}
		return builder.toString();
	}
	
	private String buildSelectAllQuery(Object[][] fieldsAndValues, String table){
		StringBuilder builder=new StringBuilder();
		builder.append("SELECT {patient.*} FROM "+table+" WHERE ");
		for(int i=0; i<fieldsAndValues.length; i++){
			if(i<fieldsAndValues.length-1){
				builder.append(fieldsAndValues[i][0]+"='"+fieldsAndValues[i][1]+"' AND ");
			}else{
				builder.append(fieldsAndValues[i][0]+"='"+fieldsAndValues[i][1]+"'");
			}
		}
		return builder.toString();
	}	

	
	private String buildDeleteQuery(Object[][] fieldsAndValues, String table){
		StringBuilder builder=new StringBuilder();
		builder.append("DELETE FROM "+table+" WHERE ");
		for(int i=0; i<fieldsAndValues.length; i++){
			if(i<fieldsAndValues.length-1){
				builder.append(fieldsAndValues[i][0]+"='"+fieldsAndValues[i][1]+"' AND ");
			}else{
				builder.append(fieldsAndValues[i][0]+"='"+fieldsAndValues[i][1]+"'");
			}
		}
		return builder.toString();
	}
	
	public Boolean deleteEntry(Object[][] fieldsAndValues, String table){
		Boolean isSuccesful=false;
		Session session = PatientDetailsHibernateUtil.getSessionFactory().getCurrentSession();
		try{
			session.beginTransaction();
			SQLQuery query=session.createSQLQuery(this.buildDeleteQuery(fieldsAndValues, table));
			int no_of_rows=query.executeUpdate();
			if(no_of_rows>0){
				isSuccesful=true;
			}
		}catch(HibernateException e){
			isSuccesful=false;
		}finally{
			session.close();
		}
		return isSuccesful;
	}
	
	public Boolean update(Patient patient){
		Boolean isSuccessful=false;
		Session session = PatientDetailsHibernateUtil.getSessionFactory().getCurrentSession();
		try{
			session.beginTransaction();
			Patient patient1=(Patient)session.get(Patient.class,patient.getPatientId());
			if(patient.getNicNo()==null){}else{patient1.setNicNo(patient.getNicNo());}
			if(patient.getPrefix()==null){}else{patient1.setPrefix(patient.getPrefix());}
			if(patient.getGivenName()==null){}else{patient1.setGivenName(patient.getGivenName());}
			if(patient.getFamilyName()==null){}else{patient1.setFamilyName(patient.getFamilyName());}
			if(patient.getNicNo()==null){}else{patient1.setNicNo(patient.getNicNo());}
			if(patient.getGender()==null){}else{patient1.setGender(patient.getGender());}
			if(patient.getBirthTime()==null){}else{patient1.setBirthTime(patient.getBirthTime());}
			if(patient.getBirthPlaceAddress()==null){}else{patient1.setBirthPlaceAddress(patient.getBirthPlaceAddress());}
			if(patient.getMultipleBirthIndex()==null){}else{patient1.setMultipleBirthIndex(patient.getMultipleBirthIndex());}
			if(patient.getMultipleBirthOrderNumber()==null){}else{patient1.setMultipleBirthOrderNumber(patient.getMultipleBirthOrderNumber());}
			if(patient.getOrganDonorIndex()==null){}else{patient1.setOrganDonorIndex(patient.getOrganDonorIndex());}
			if(patient.getMaritialStatus()==null){}else{patient1.setMaritialStatus(patient.getMaritialStatus());}
			if(patient.getEducationalLevelId()==null){}else{patient1.setEducationalLevelId(patient.getEducationalLevelId());}
			if(patient.getLivingArrangementId()==null){}else{patient1.setLivingArrangementId(patient.getLivingArrangementId());}
			if(patient.getReligiousAffliationId()==null){}else{patient1.setReligiousAffliationId((patient.getReligiousAffliationId()));}
			if(patient.getEthnicGroupId()==null){}else{patient1.setEthnicGroupId(patient.getEthnicGroupId());}
			if(patient.getConfidentialityLevelId()==null){}else{patient1.setConfidentialityLevelId(patient.getConfidentialityLevelId());}
			if(patient.getVeryImportantPatientId()==null){}else{patient1.setVeryImportantPatientId(patient.getVeryImportantPatientId());}
			if(patient.getDeceasedIndex()==null){}else{patient1.setDeceasedIndex(patient.getDeceasedIndex());}
			if(patient.getDeceasedTime()==null){}else{patient1.setDeceasedTime(patient.getDeceasedTime());}
			if(patient.getIsActive()==null){}else{patient1.setIsActive(patient.getIsActive());}
			session.update(patient1);
			session.getTransaction().commit();
			isSuccessful=true;
		}catch(HibernateException e){
			isSuccessful=false;
			throw e;
		}
		return isSuccessful;
	}
	
	public boolean DeletePatient(int patientId){
		Boolean isSuccessful=false;
		Session session = PatientDetailsHibernateUtil.getSessionFactory().getCurrentSession();
		try{
			session.beginTransaction();
			Patient patient1=(Patient)session.get(Patient.class,patientId);
			patient1.setIsActive(false);
			session.update(patient1);
			session.getTransaction().commit();
			isSuccessful=true;
		}catch(HibernateException e){
			isSuccessful=false;
			throw e;
		}
		return isSuccessful;
	}

}
